package com.view.bp.common;

import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;

/**
 * @author hzj
 * @date 2020/12/31 10:34
 */
@Aspect
@Component
@Log4j2
public class projectAspect {
//    private final Logger log = LoggerFactory.getLogger(projectAspect.class);

    //统一切点,对controller及其子包中所有的类的所有方法切面
    @Pointcut("execution(public * com.view.bp.controller..*.*(..))")
    public void Pointcut() {
    }

    //前置通知
    @Before("Pointcut()")
    public void beforeMethod(JoinPoint joinPoint){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();//这个RequestContextHolder是Springmvc提供来获得请求的东西
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
        // 记录下请求内容
        log.info("------------URL : "+ "---" + request.getRequestURL().toString());
        log.info("------------HTTP_METHOD : "+ "---"+ request.getMethod());
        log.info("------------IP : "+ "---" + request.getRemoteAddr());
        log.info("------------THE ARGS OF THE CONTROLLER : "+ "---" + Arrays.toString(joinPoint.getArgs()));

        //下面这个getSignature().getDeclaringTypeName()是获取包+类名的   然后后面的joinPoint.getSignature.getName()获取了方法名
        log.info("------------CLASS_METHOD : "+ "---" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        //logger.info("------------TARGET: " + joinPoint.getTarget());//返回的是需要加强的目标类的对象
        //logger.info("------------THIS: " + joinPoint.getThis());//返回的是经过加强后的代理类的对象
    }

    //@After: 后置通知
    @After("Pointcut()")
    public void afterMethod(JoinPoint joinPoint){
        log.info("调用了后置通知");
    }
    //@AfterRunning: 返回通知 rsult为返回内容
    @AfterReturning(value="Pointcut()",returning="result")
    public void afterReturningMethod(JoinPoint joinPoint,Object result){
        System.out.println("------------the return of the method is : "+"---" + result);
    }
    //@AfterThrowing: 异常通知
    @AfterThrowing(value="Pointcut()",throwing="ex")
    public void afterReturningMethod(JoinPoint joinPoint, Exception ex){
        String methodName = joinPoint.getSignature().getName();
        List<Object> args = Arrays.asList(joinPoint.getArgs());
        System.out.println("------------"+ "---"+"连接点方法为：" + methodName + ",参数为：" + args + ",异常为：" + ex);
    }

    //@Around：环绕通知
    @Around("Pointcut()")
    public Object Around(ProceedingJoinPoint pjp) throws Throwable {
        log.info("around执行方法之前");
        Object object = pjp.proceed();
        log.info("around执行方法之后--返回值：" +object);
        return object;
    }

}